Spring 3引入了一些验证支持的增强。首先,JSR-303 Bean Validation API现在已经完全支持了。其次,在以编码的方式Spring的DataBinder时,他可以绑定对象并校验他们。第三,Spring MVC现在支持声明性的验证@Controller
输入。
JSR-303标准化了Java平台的约束声明和元数据。使用此API,你可以用声明性的约束注释model的属性,它们会在运行时被强制执行。 有许多内置的约束你可以使用。你也可以定义自己的约束。
为了说明,请考虑一个拥有两个属性的简单Person model:
public class PersonForm {
private String name;
private int age;
}
JSR-303允许你对这些属性使用约束性声明:
public class PersonForm {
@NotNull
@Size(max=64)
private String name;
@Min(0)
private int age;
}
Spring提供了对Bean Validation API的全完支持。这包括了方便的将JSR-303/JSR-349 Bean Validation提供者作为Spring Bean方便的加载。这允许javax.validation.ValidatorFactory
或javax.validation.Validator
在你应用程序任何需要验证的地方呗注入。
使用LocalValidatorFactoryBean
将默认的Validator配置为一个Spring Bean:
<bean id="validator"
class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/>
上述基本的配置会通过它默认的运行机制初始化Bean Vlidation。被期待存在类路径下的JSR-303/JSR-349提供者,和Hebernate Validator,会被自动的检测。
LocalValidatorFactoryBean
同时实现了javax.validation.ValidatorFactory
和javax.validation.Validator
,以及Spring的org.springframework,validation.Validator
。你可以将这些接口的引用注入到需要调用验证逻辑的bean中。
如果你偏爱直接使用Bean Validation API,你可以注入一个javax.validation.Validator
:
import javax.validation.Validator;
@Service
public class MyService {
@Autowired
private Validator validator;
如果你的Bean需要Spring Validation API,那可以注入一个org.springframework.validation.Validator
的引用:
import org.springframework.validation.Validator;
@Service
public class MyService {
@Autowired
private Validator validator;
}
每一个Bean Validation约束有两部分组成。首先,一个@Constraint
注解用来声明约束和它配置的属性。其次,一个javax.validation.ConstraintValidation
接口的实现类来实现约束的行为。为了联合声明和实现,每一个@Contraint
注解引用了对应的校验约束的实现类。在运行时,ConstraintValidatorFactory
会当在你领域模型中遇到约束性注解是实例化实现。
默认的,LocalValidatorFactoryBean
配置了一个SpringConstriantValidatorFactory
来通过Spring去创建ConstraintValidator实例。这允许你自定义的ConstraintValidators像其他任何Spring bean一样受益于依赖注入。
下面是一个自定义的@Constraint
声明的例子,紧跟着的是和约束结合使用的ConstraintValidator
实现,并且用到了Spring的依赖注入:
@Target({ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy=MyConstraintValidator.class)
public @interface MyConstraint {
}
import javax.validation.ConstraintValidator;
public class MyConstraintValidator implements ConstraintValidator {
@Autowired;
private Foo aDependency;
...
}
正如你所见,一个ConstraintValidator实现能够像其他Spring bean一样有自己的依赖@Autowired。
Bean Validation 1.1和Hibernate Validator 4.3的自定义拓展提供了方法校验的特征,都可以通过MethdoValidationPostProcessor
bean定义被集成到Spring上下文中:
<bean class="org.springframework.validation.beanvalidation.MethodValidationPostProcessor"/>
为了符合Spring-驱动方法校验的条件,全部的类必须要用Spring的@Validated注解,可以选择声明使用的验证组。查看MethodValidationPostProcessor
java文档查看更过关于设置Hibernate Validator和Bean Validation1.1提供者的详情。
默认的LocalValidatorFactoryBean
配置对为大部分情况是足够的。对于各种Bean Validation结构,有许多配置选项,从消息插入到遍历方式。查看LocalValidatorFactoryBean
java文档查看这些选项的更多信息。
从Spring 3起,一个DataBinder实例可以配置一个Validator。一旦被配置,调用binder.validate()
时会调用Validator。校验错误会自动被添加到binder的BindingResult中。
当以代码的方式使用DataBinder时,可以在绑定目标对象之后调用校验逻辑:
Foo target = new Foo();
DataBinder binder = new DataBinder(target);
binder.setValidator(new FooValidator());
// bind to the target object
binder.bind(propertyValues);
// validate the target object
binder.validate();
// get BindingResult that includes any validation errors
BindingResult results = binder.getBindingResult();
一个DataBinder也可以通过dataBinder.addValidators
和dataBinder.replaceValidators
来配置多个Validator
实例。这在结合全局配置的Bean Validation到本地DataBinder实例上配置的Spring Validation时十分有用。